/**
 * 第三课 接口
 */
interface Iobj {
    name: string;
    age?: 12;//不是必须的
    readonly sex?: number;
    [propName: string]: any;
}

let stu: Iobj = { name: '张三', sex: 0 };
function getName(stu: Iobj) {
    let a = stu.age;
    return stu.name;
}
// console.log(getName({name:'jack'}));
let number = [1, 2, 3];
let ro: ReadonlyArray<number> = number;
console.log(ro); // [ 1, 2, 3 ]

function test(arg: Iobj) {
    console.log(arg);//{ name: 'jack', width: 'we' }
}
test({ name: 'jack', width: 'we' })
// 接口中定义的一个函数
interface SearFun {
    (source: string, subString: string): boolean;
}
// 使用接口函数，我们不需要将参数名相同，接口中的函数中的参数个数及参数类型，下面在实现接口使用该函数的时候函数参数个数及类型会优先匹配接口中函数参数
let resFun: SearFun = (src: string, sus: string) => {
    let result = src.search(sus);/*  */
    return result > -1;
}

// 在使用可索引类型时
interface StringArray {
    // 其中index是随意写的
    [index: number]: string;
}

let myArray: StringArray;
myArray = ['lucy', 'jack'];
// number是索引的类型，比如myArray[0],上述的number就是此处的0，返回的结果“lucy”的类型时上面的string类型
console.log(myArray[0]);

interface UserObj {
    // 当前能使用的索引类型及返回值
    [index: string]: string;
    [index: number]: string;
}
// 对象接口也是一致
var arr: UserObj = { name: '张三', age: "32", 1: '43' };
console.log(arr['name']);//'张三'
console.log(arr[1]);//43
// 使用类来作为可索引接口的返回值时
class Animal {
    age: number;
    color: string;
}
// 继承Animal
class Dog extends Animal {
    size: number;
}

interface NotOkay {
    [x: number]: Animal;
    [x: string]: Animal;
}
let aanimal = new Animal();
aanimal.age = 23;
aanimal.color = 'red';
let xx: NotOkay = { 'a': aanimal, 12: aanimal };
console.log(xx[12].age === xx['a'].age);  // true

// 实现一个接口
interface Idate {
    curTime: Date;
    getTime();
}
// 在实现Idate接口后，务必拥有curTime属性并且是Date类型,若接口中拥有方法，则也需要实现该方法
class Ctime implements Idate {
    curTime: Date;
    getTime() { }
}


interface Shape {
    color: string;
}

interface Square extends Shape {
    sideLength: number;
}

let square = <Square>{};
square.color = "blue";
square.sideLength = 10;

console.log('-----------');


interface Counter {
    // 定义一个调用签名函数，返回值为string类型
    (start: number): string;
    // number属性
    interval: number;
    // 一个返回值为空的函数reset
    reset(): void;
}
function getCounter(): Counter {
    // 该方法返回一个字符串；
    let counter = <Counter>function (start: number) { start += 2; return start + ''; };
    counter.interval = 123;
    counter.reset = function () { };
    return counter;
}

let cc = getCounter();
console.log(cc(10));//12 字符串类型
cc.reset();
cc.interval = 5.0;

class A {
    public name: string;
}
interface IA extends A {
    select(): void;
    age: number;
}
class B extends A implements IA {
    select() { };
    age: 2;
}
class C implements IA {
    select() { };
    age: 32;
    name: 'jack'
}




